// https://leetcode.cn/problems/network-delay-time/
/**
 * 网络延迟时间
 * 有 n 个网络节点，标记为 1 到 n。

给你一个列表 times，表示信号经过 有向 边的传递时间。 times[i] = (ui, vi, wi)，其中 ui 是源节点，vi 是目标节点， wi 是一个信号从源节点传递到目标节点的时间。

现在，从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号？如果不能使所有节点收到信号，返回 -1 。


示例 1：

输入：times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
输出：2
示例 2：

输入：times = [[1,2,1]], n = 2, k = 1
输出：1
示例 3：

输入：times = [[1,2,1]], n = 2, k = 2
输出：-1
 
提示：

1 <= k <= n <= 100
1 <= times.length <= 6000
times[i].length == 3
1 <= ui, vi <= n
ui != vi
0 <= wi <= 100
所有 (ui, vi) 对都 互不相同（即，不含重复边）
 */

/**
 * 思路：并查集 有误
 * 这题应该为使用Dijkstra算法
 * 1. 初始化Dijkstra列表
 * 2. 初始化Dijkstra列表的权值
 * 3. 从Dijkstra列表中，挑选一个没有没选中的，但权值最低的节点
 * 4. 更新当前节点的相邻节点的权值
 * 5. 重复3、4，直到所有节点都收到信号
 */

class DisJoint {
    constructor(num) {
        this.num = num;
        // 记录每个节点的祖先节点
        this.fa = new Array(num + 1).fill(-1).map((_, idx) => [idx, 0]);
    }

    /**
     * 一条从i到j的路径
     * - 将i元素的祖先节点设置为j元素的祖先
     * @param {*} i
     * @param {*} j
     */
    union(i, j, value) {
        this.fa[j] = this.find(i, value);
        console.log(JSON.stringify(this.fa));
    }

    find(i, reduceCost = 0) {
        if (this.fa[i][0] === i) {
            return [i, reduceCost];
        }

        reduceCost += this.fa[i][1];
        return this.find(this.fa[i][0], reduceCost);
    }

    fetchRoot(rootIndex) {
        let root = rootIndex;
        let ret = [];

        this.fa.forEach((i) => {
            if (i[0] === root) {
                ret.push(i);
            }
        });

        return ret;
    }
}

var networkDelayTime = function (times, n, k) {
    let dj = new DisJoint(n);

    for (let i = 0; i < times.length; i++) {
        let [from, to, cost] = times[i];
        dj.union(from, to, cost);
    }

    let rootArr = dj.fetchRoot(k);

    if (rootArr.length !== n) {
        return -1;
    }

    return Math.max(...rootArr.map((i) => i[1]));
};

// let dj = new DisJoint(4);
// dj.union(2, 1, 1);
// dj.union(2, 3, 1);
// dj.union(3, 4, 1);

// console.log(JSON.stringify(dj.fetchRoot(2)));

// let dj = new DisJoint(2);
// dj.union(1, 2, 1);
// console.log(JSON.stringify(dj.fetchRoot(2)));

console.log(
    networkDelayTime(
        [
            [2, 1, 1],
            [2, 3, 1],
            [3, 4, 1],
        ],
        4,
        2
    )
);

console.log(networkDelayTime([[1, 2, 1]], 2, 1));

console.log(networkDelayTime([[1, 2, 1]], 2, 2));
